package ngat.oss;

import java.io.*;

/** Class used to transfer details of changes to Schedule Weighting functions from a
 * Control Client via CTRL_SetScheduleParams_Req(WeightingParameters, funcRef). 
 * WeightingParameters are stored as statics in Scheduling and used to implement
 * the weighting functions by the Database objects' schedule() methods.
 * The X-axis scales are in units specified in the database objects rather than the
 * convenience units used in the user interface which collects this data.
 *
 * $Id: WeightingParameters.java,v 1.1 2006/11/27 08:45:00 snf Exp $
 *
 */
public class WeightingParameters implements Serializable {

    /** Endpoint behaviour. Continues at Minimum value. */
    public static final int MIN = 0;
    /** Endpoint behaviour. Continues at Maximum value. */
    public static final int MAX = 1;

    /** Holds the x values of the anchor points. */
    protected double [] xArgs;
    /** Holds the y values of the anchor points. */
    protected double [] yArgs;

    /** Low limit of the veto function mask. */
    protected double vetoLow;

    /** High limit of the veto function mask. */
    protected double vetoHi;
    
    /** Y-axis scale factor. Determines the relative importance of this weighting 
     * function with reference to the other functions. */
    protected double beta;

    /** True if the veto function mask is high between the veto low and hi limits.
     * False if the veto function mask is low between the veto low and hi limits. */
    protected boolean vetoInclusive;

    /** Specifies the trend below the first (low) anchor point. */
    protected int loTrend;

    /** Specifies the trend above the last (hi) anchor point. */
    protected int hiTrend;

    protected int numArgs;

    public WeightingParameters(double [] xArgs, double [] yArgs, double beta, double vetoLow, double vetoHi, boolean inclusive) {
	this.xArgs = xArgs;
	this.yArgs = yArgs;
	this.beta = beta;
	this.vetoLow = vetoLow;
	this.vetoHi = vetoHi;
	this.vetoInclusive = inclusive;
	numArgs = xArgs.length;
	System.out.println("WP--- numargs: "+numArgs);
	if (xArgs[0] < xArgs[numArgs-1]) {
	    loTrend = MIN; 
	    hiTrend = MAX;
	} else {
	    loTrend = MAX;
	    hiTrend = MIN;
	}	
    }

    /** Returns the set of x values. */
    public double [] getXArgs() { return xArgs;}

    /** Returns the set of y values. */
    public double [] getYArgs() { return yArgs;}

    /** Returns the Lo end trend. */
    public double getVetoLow() { return vetoLow;}

    /** Sets the veto low limit. */
    public void setVetoLow(double low) { this.vetoLow = low;}

    /** Returns the Hi end trend. */
    public double getVetoHi() { return vetoHi;}

    /** Sets the veto hi limit. */
    public void setVetoHi(double hi) { this.vetoHi = hi;}

    /** Returns the Y-scale factor. */
    public double getBeta() { return beta;}

    /** Sets the Y-sclae factor. */
    public void setBeta(double beta) { this.beta = beta;}

    /** Returns true if the veto function is inclusive (high between its limits).*/
    public boolean vetoIsInclusive() { return vetoInclusive; }

    /** Returns true if the veto function is exclusive (low between its limits).*/
    public boolean vetoIsExclusive() { return !vetoInclusive;}
    
    /** Sets the inclusive/exclusive flag for the veto function mask.*/
    public void setVetoIsInclusive(boolean inclusive) { this.vetoInclusive = inclusive;}
    
    /** Apply the weighting function to a supplied x value. */
    public double evaluate(double x) {
	
	double result = 0.0;
	
	// Arg below low point.
	if (x < xArgs[0]) {
	    //  switch (loTrend) {	   
//  	    case MIN:
//  		result = Math.min(yArgs[0], yArgs[numArgs-1]);
//  		break;
//  	    case MAX:
//  		result = Math.max(yArgs[0], yArgs[numArgs-1]);
//  		break;
//  	    }
	    result = yArgs[0];
	    
	    return beta*result;
	    
	}
	
	// Arg above hi point.
	
	if (x > xArgs[numArgs-1]) {
	   //   switch (hiTrend) {
//  	    case MIN:
//  		result = Math.min(yArgs[0], yArgs[numArgs-1]);
//  		break;
//  	    case MAX:
//  		result = Math.max(yArgs[0], yArgs[numArgs-1]);
//  		break;
//  	    }
	    result = yArgs[numArgs-1];

	    return beta*result;
	} 
	
	// Arg in one of segments..
	
	int k = 0;
	for (int j = 0; j < numArgs -1; j++) {
	    if (xArgs[j] < x && x <= xArgs[j+1]) k = j;
	}
	double slope = (yArgs[k+1] - yArgs[k])/(xArgs[k+1] - xArgs[k]);
	return  beta*(slope*(x - xArgs[k]) + yArgs[k]);
    }

    /** Returns true if:-
     * Veto mask is inclusive AND x lies inside [ vetoLo, vetoHi ]
     * Veto mask is exclusive AND x lies outside [ vetoLo, vetoHi ]. */
    public boolean inRange(double x) {
	if (vetoInclusive &&
	    (x < vetoLow || x > vetoHi)) return false;
	if (!vetoInclusive &&
	    (x > vetoLow && x < vetoHi)) return false;
	return true;
    }
  
}


/** $Log: WeightingParameters.java,v $
/** Revision 1.1  2006/11/27 08:45:00  snf
/** Initial revision
/**
/** Revision 1.1  2006/11/27 08:37:05  snf
/** Initial revision
/**
/** Revision 1.2  2000/11/29 12:55:41  snf
/** Telescope status information.
/**
/** Revision 1.1  2000/11/22 14:13:21  snf
/** Initial revision
/** */


